#ifndef NETWORK_H
#define NETWORK_H

#include <QVector>
#include "nodes/node.h"

enum Direction
{
    UP,
    DOWN
};

class NodeDirectionTuple
{
public:
    Node * node;
    Direction dir;

    NodeDirectionTuple() : node(0), dir(UP)
    { }

    NodeDirectionTuple(const NodeDirectionTuple & t)
    {
        node = t.node;
        dir  = t.dir;
    }

    NodeDirectionTuple(Node * n) : node(n), dir(UP)
    { }

    NodeDirectionTuple(Node * n, Direction d) : node(n), dir(d)
    { }

    bool operator==(const NodeDirectionTuple &b)
    {
        return node == b.node && dir == b.dir;
    }

};

class Network
{

private:

    QVector<Node *> * nodes;
    QVector<QVector<double> * > * samples;


public:    

    Network();    
    ~Network();

    Node * getNode(int i);

    QVector<Node *> * getNodes();
    QVector<double> * getSamplesForNode(int i);

    int numNodes();
    void addNode(Node * n);
    void addSubnet(Network * n);
    void generateSamples(int N, int burn);    
    void computeStats(int numBins = 100, bool saveStats = false);
    void print();

    void plotHistograms(QString path);
    void plotMixingGraphs(QString path);

    void saveSamples(QString path);

    QVector<Node *> * prune(QVector<Node *> * queryNodes, QVector<Node *> * observedNodes);
    static void addNodeTuplesToList(QVector<NodeDirectionTuple> * list, QVector<Node*> nodes, Direction dir);
    static void addNodeTuplesToList(QVector<NodeDirectionTuple> * list, QVector<Node*> * nodes, Direction dir);

    void toDotFile(QString filename, QVector<Node *> * highlightNodes = NULL, QVector<Node *> * keepNodes = NULL);
};

#endif // NETWORK_H
